SpringBoot With IoC,DI, AOP,自动配置

您所在的位置:网站首页 ioc springboot SpringBoot With IoC,DI, AOP,自动配置

SpringBoot With IoC,DI, AOP,自动配置

2023-03-11 03:28| 来源: 网络整理| 查看: 265

文章目录 1 IoC(Inverse Of Controller)2 DI(Dependency Injection)3 AOP(面向切面编程)3.1 什么是AOP?3.2 AOP的作用?3.3 AOP的核心概念3.4 AOP常见通知类型3.5 切入点表达式3.5.1 切入点表达式练习一3.5.2 切入点表达式练习二3.5.3 抽取冗余切入点表达式3.5.4 抽取冗余切入点表达式示例 3.6 连接点 4 自动配置4.1 简述:SpringBoot自动配置的原理4.2 源码跟踪

说明:IoC、DI均为软件工程中思想,致力提高“高内聚,低耦合”的软件设计思路。

1 IoC(Inverse Of Controller)

什么是IOC?(Inverse Of Controller)控制反转,把对象的创建权(new对象), 反转为 Spring容器管理,IOC创建的对象称之为Bean对象。

1.1 声明bean的注解?(即把对象放入容器中的注解)

注解说明@Component不属于以上三类时,用此注解@Controller标注在控制层类上@Service标注在业务类上@Repository标注在数据访问层类上 2 DI(Dependency Injection)

什么是DI?(Dependency Injection)依赖注入,给容器中bean的属性赋值,常用使用方式,使用@Autowired注解声明在需要注入的类上,此时就会去spring容器中寻找Bean对象。

2.1 依赖注入的注解?

注解说明@Autowired按照类型注入@Qualifier按照名称注入 要和@Autowired搭配使用@Resource按照名称注入 = @Autowired + @Qualifier 3 AOP(面向切面编程) 3.1 什么是AOP?

面向切面编程

3.2 AOP的作用?

在不改变原始代码的基础上进行功能增强

3.3 AOP的核心概念 名词解释连接点所有可以进行功能增强的方法都是连接点切入点进行了功能增强的方法就是切入点通知共性功能切面切入点 + 通知目标对象通知所应用的对象就是目标对切入点表达式指定哪些方法是切入点 3.4 AOP常见通知类型 通知类型解释注意事项@Before前置通知@After后置通知@Around环绕通知① @Around环绕通知需要自己调用 ProceedingJoinPoint.proceed() 来让原始方法执行,其他通知不需要考虑; ② @Around环绕通知方法返回值,必须指定为Object,来接收原始方法的返回值,否则原始方法执行完毕,获取不到返回值。@AfterReturning返回后通知@AfterThrowing异常后通知 3.5 切入点表达式

写法一:@PointCut("execution(访问修饰符 返回值 包名.类名.方法名(参数))")

通配符: * 单个独立的任意符号,通配任意返回值、包名、类名、方法名、任意类型的参数,也通配包、类、方法名的一部分 .. 多个连续任意符号,用于参数省略或包名省略

写法二:@PointCut("@annotation(注解的全路径类名)")

通过连接点对象获取目标方法的信息 获取类名:joinPoint.getTarget().getClass().getName()获取方法名:joinPoint.getSignature().getName()获取参数:joinPoint.getArgs()执行目标方法:joinPoint.proceed()获取返回值:Object result = joinPoint.proceed()

切入点表达式的语法规则:

方法的访问修饰符可以省略返回值用*号代替(任意返回值类型)包名使用*号代替,代表任意包(一层包使用一个*)使用..配置包名,标识此包及此包下所有子包类名使用*号代替,标识任意类方法名使用*号代替,表示任意方法使用 * 配置参数,一个任意类型的参数使用.. 配置参数,任意个任意类型的参数 3.5.1 切入点表达式练习一

注意事项:

根据业务需要,可以使用 且(&&)、或(||)、非(!) 来组合比较复杂的切入点表达式 execution(* com.sesameseed.service.DeptService.list(..)) || execution(* com.sesameseed.service.DeptService.delete(..))

解释:切入点为DeptService接口(全路径)下,参数为任意类型和个数,且返回值为任意的list方法,或DeptService接口下,参数为任意类型和个数,且返回值为任意的delete方法。

*com*任意返回值.(. .)表示任意类型和个数的参数.DeptService.list(. .)DeptService接口下,参数为任意类型和个数的list方法表示 3.5.2 切入点表达式练习二 @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")

解释:切入点为mapper包下,任意包名,任意方法,且被@AutoFill注解声明。

3.5.3 抽取冗余切入点表达式

引入,对于下方代码来说,每一个注解里面都用到相同切入点表达式,所以我们可以把它抽取出来。

//前置通知 @Before("execution(* com.itheima.service.*.*(..))") //环绕通知 @Around("execution(* com.itheima.service.*.*(..))") //后置通知 @After("execution(* com.itheima.service.*.*(..))") //返回后通知(程序在正常执行的情况下,会执行的后置通知) @AfterReturning("execution(* com.itheima.service.*.*(..))") //异常通知(程序在出现异常的情况下,执行的后置通知) @AfterThrowing("execution(* com.itheima.service.*.*(..))") 3.5.4 抽取冗余切入点表达式示例 注解说明@PointCut将公共的切入点表达式抽取出来 @Slf4j @Component @Aspect public class MyAspect1 { //切入点方法(公共的切入点表达式) @Pointcut("execution(* com.itheima.service.*.*(..))") private void pt(){ } //前置通知(引用切入点) @Before("pt()") public void before(JoinPoint joinPoint){ log.info("before ..."); } //环绕通知 @Around("pt()") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { log.info("around before ..."); //调用目标对象的原始方法执行 Object result = proceedingJoinPoint.proceed(); //原始方法在执行时:发生异常 //后续代码不在执行 log.info("around after ..."); return result; }

注意:在当前类外部引切入点表达式,需要把private改为public,语法为全类名.方法名(),示例如下:

public class MyAspect2 { //引用MyAspect1切面类中的切入点表达式 @Before("com.itheima.aspect.MyAspect1.pt()") public void before(){ log.info("MyAspect2 -> before ..."); } } 3.6 连接点

连接点:可以被AOP控制的方法

在Spring中JoinPoint抽象连接点,可以获得方法执行时相关信息,如目标类名、方法名、方法参数等。

通知类型获取连接点信息方法@AroundProceedingJoinPoint类型其他四种通知JoinPoint类型

3.6.1 代码示例

@Pointcut("@annotation(com.itheima.anno.MyLog)") private void pt(){} //前置通知 @Before("pt()") public void before(JoinPoint joinPoint){ log.info(joinPoint.getSignature().getName() + " MyAspect7 -> before ..."); } //后置通知 @Before("pt()") public void after(JoinPoint joinPoint){ log.info(joinPoint.getSignature().getName() + " MyAspect7 -> after ..."); } //环绕通知 @Around("pt()") public Object around(ProceedingJoinPoint pjp) throws Throwable { //获取目标类名 String name = pjp.getTarget().getClass().getName(); log.info("目标类名:{}",name); //目标方法名 String methodName = pjp.getSignature().getName(); log.info("目标方法名:{}",methodName); //获取方法执行时需要的参数 Object[] args = pjp.getArgs(); log.info("目标方法参数:{}", Arrays.toString(args)); //执行原始方法 Object returnValue = pjp.proceed(); return returnValue; } 4 自动配置 4.1 简述:SpringBoot自动配置的原理

在Springboot启动的时候,会用到核心注解@SpringBootApplication,这个注解中有一个自动配置注解@EnableAutoConfiguration,自动配置注解会自动寻找spring.factories 和 AutoConfiguration.imports 文件中的xxxAutoConfiguration自动配置类,在自动配置中使用@Bean注解把一些配置类和bean对象放到了Spring容器中,就完成了自动配置

自动配置注解:@EnableAutoConfiguration自动配置文件:spring.factories 和 AutoConfiguration.imports 文件自动配置类:xxxAutoConfiguration(@Bean). 注解说明@Bean告诉方法,产生一个Bean对象并交给Spring管理。产生这个Bean对象的方法Spring只会调用一次,随后被放在Spring容器中。 4.2 源码跟踪

spring.factories Spring Boot 中的SPI 机制(Java SPI 机制):为某个接口寻找服务的实现的机制,类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制很重要。

当需要实现SDK 或Sring boot starter 给别人调用,使用Factories机制(Spring Boot 中的SPI 机制)可以让SDK或Stater的使用只需很少或不需要进行配置,只需在服务中引入我们的Jar包就即可。

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3